home *** CD-ROM | disk | FTP | other *** search
- // sysex: (c) Günter Nagler 1996
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include <stdlib.h>
- #include <conio.h>
- #include "filei3.hpp"
- #include "sndcard.hpp"
-
- static char* version = "sendsyx v1.0 by Günter Nagler (" __DATE__ ")";
-
- Soundcard* card = 0;
-
- char* inputname = 0;
- int echo = 0;
- long skip = 0;
- long count = 0x7fffffffL;
- int isbinary = 0;
- int encode = 0;
- int binaryencode = 0;
- unsigned char dumb[8];
- unsigned char byte[7];
- int bytelen = 0;
- long sum = 0;
- int reply = 1;
-
- int escape()
- {
- static int esc = 0;
-
- if (esc)
- return 1;
- while (kbhit())
- if (getch() == 27)
- return esc = 1;
- return 0;
- }
-
- void checkreply()
- {
- #define RETRY 100
-
- printf("waiting for reply...");
-
- unsigned char buf[1024], data;
-
- int insysex = 0;
-
- card->startinput();
- for (int i = 0; i < RETRY; i++)
- {
- int len = card->hear(buf, sizeof(buf));
- if (len <= 0)
- {
- if (escape())
- break;
- continue;
- }
- for (int j = 0; j < len; j++)
- {
- data = buf[j];
- if (insysex)
- {
- printf(" %02x", data); // should be F7
- if (data & 0x80)
- break;
- }
- else
- {
- if (data == 0xf0)
- {
- printf("\nreply: %02x", data);
- insysex = 1;
- }
- else
- ;
-
- // ignore
- }
- }
- if (j < len)
- break;
- }
- card->stopinput();
- if (insysex)
- printf("\n");
- else
- printf(" no reply\n");
- }
-
- void checkresponse()
- {
- #define RESPONSE_RETRY 1000
-
- card->startinput();
-
- unsigned char data;
-
- for (long i = 0; i < RESPONSE_RETRY; i++)
- if (card->hear(&data, 1))
- break;
- if (i == RETRY)
- fprintf(stderr, "Warning: no response. Transfer might not work.\n");
- card->stopinput();
- }
-
- int flushbytes()
- {
- if (bytelen == 0)
- return 1;
- int dumblen = code7to8(byte, bytelen, dumb);
- bytelen = 0;
- sum += dumblen;
- return card->play(dumb, dumblen) == dumblen;
- }
-
- int sendbyte(unsigned char data)
- {
- if (encode)
- {
- // add to encode buffer
- byte[bytelen++] = data;
- if (bytelen == 7)
- return flushbytes();
- return 1;
- }
- else if (bytelen > 0) // buffer contains data to encode
- {
- if (!flushbytes())
- return 0;
- }
- sum ++;
- if (card->play(&data, 1) != 1)
- {
- fprintf(stderr, "could not send byte %s\n", data);
- return 0;
- }
- if (echo)
- printf("%02X ", data);
- return 1;
- }
-
- int sendbytes(unsigned char* data, int len)
- {
- if (!data)
- return 0;
- while (len-- > 0)
- {
- if (!sendbyte(*data++))
- return 0;
- }
- return 1;
- }
-
- int sendcontrol(unsigned char ctrl, unsigned char val)
- {
- unsigned char data[3];
-
- data[0] = 0xb0;
- data[1] = ctrl;
- data[2] = val;
- for (int c = 0; c < 16; c++)
- {
- sum += 3;
- if (!card->play(data, 3))
- return 0;
- data[0]++;
- }
- return 1;
- }
-
- int testbinary(FILE* f)
- {
- long oldpos = ftell(f);
- int c;
-
- while ((c = fgetc(f)) != EOF)
- {
- if (c < ' ' && !isspace(c))
- break;
- if (c >= 0x80)
- break;
- }
- fseek(f, oldpos, SEEK_SET);
- if (c == EOF)
- return 0;
- else
- return 1;
- }
-
- int get(FILE* inf, char* &inbuf)
- {
- if (inbuf)
- {
- if (*inbuf == 0)
- return EOF;
- else
- return *inbuf++;
- }
- if (inf)
- return fgetc(inf);
- return EOF;
- }
-
- int sendsysex(char* filename);
-
- int hexval(int c)
- {
- if (isdigit(c))
- return c - '0';
- else if (isxdigit(c))
- return toupper(c) - 'A' + 10;
- else
- return -1;
- }
-
- int hexval(char* s)
- {
- int v1, v2;
-
- if (!s || (v1 = hexval(*s)) < 0)
- return -1;
- if (s[1] == 0)
- return v1;
- if (s[2])
- return -1;
- v2 = hexval(s[1]);
- if (v2 < 0)
- return -1;
- return (v1 << 4) + v2;
- }
-
- int sendtextsyx(FILE* f, char* buf)
- {
- int c = get(f, buf);
- // assume text
- while (c != EOF)
- {
- if (escape())
- break;
- if (isspace(c))
- ;
- else if (c == '/')
- {
- c = get(f, buf);
- if (c == '/')
- {
- while (c != EOF && c != '\n')
- c = get(f, buf);
- }
- else
- {
- fprintf(stderr, "invalid character / ignored\n");
- continue;
- }
- }
- else
- {
- char ident[128];
- int len = 0;
- // keyword?
-
- while (c != EOF && !isspace(c))
- {
- if (len < sizeof(ident)-1)
- ident[len++] = c;
- c = get(f, buf);
- }
- ident[len] = '\0';
-
- int value;
-
- if ((value = hexval(ident)) >= 0)
- {
- if (!sendbyte(value))
- break;
- continue;
- }
-
- if (stricmp(ident, "gmon") == 0)
- {
- if (!sendbytes("\xF0\x7E\x7F\x09\x01\xF7", 6))
- break;
- }
- else if (stricmp(ident, "identify") == 0)
- {
- if (!sendbytes("\xf0\x7e\x00\x06\x01\xf7", 6))
- break;
- }
- else if (stricmp(ident, "xgon") == 0)
- {
- if (!sendbytes("\xF0\x08\x43\x10\x4c\x00\x00\x7e\x00\xf7", 10))
- break;
- }
- else if (stricmp(ident, "gson") == 0)
- {
- if (!sendbytes("\xF0\x0a\x41\x10\x42\x12\x40\x00\x7f\x00\x41\xf7", 12))
- break;
- }
- else if (stricmp(ident, "gsoff") == 0)
- {
- if (!sendbytes("\xF0\x0a\x41\x10\x42\x12\x40\x00\x7f\x7f\x42\xf7", 12))
- break;
- }
- else if (stricmp(ident, "localon") == 0)
- {
- if (!sendcontrol(0x7a, 127))
- break;
- }
- else if (stricmp(ident, "localoff") == 0)
- {
- if (!sendcontrol(0x7a, 0))
- break;
- }
- else if (stricmp(ident, "notesoff") == 0)
- {
- if (!sendcontrol(0x7b, 0))
- break;
- }
- else if (stricmp(ident, "omnioff") == 0)
- {
- if (!sendcontrol(0x7c, 0))
- break;
- }
- else if (stricmp(ident, "omnion") == 0)
- {
- if (!sendcontrol(0x7d, 0))
- break;
- }
- else if (stricmp(ident, "polyoff") == 0)
- {
- if (!sendcontrol(0x7e, 0))
- break;
- }
- else if (stricmp(ident, "polyon") == 0)
- {
- if (!sendcontrol(0x7f, 0))
- break;
- }
- else if (stricmp(ident, "sox") == 0)
- {
- if (!sendbyte(0xf0))
- break;
- }
- else if (stricmp(ident, "eox") == 0)
- {
- if (!sendbyte(0xf7))
- break;
- }
- else
- {
- // try if it is a filename
- FILE* f = fopen(ident, "rb");
- if (f)
- {
- fclose(f);
- sendsysex(ident);
- continue;
- }
- else if (strchr(ident, '.'))
- perror(ident);
- else
- fprintf(stderr,"unknown identifier %s ignored\n", ident);
- return 0;
- }
- continue;
- }
- c = get(f, buf);
- }
- return 1;
- }
-
- int sendsysex(char* filename)
- {
- FILE* f = fopen(filename, "rb");
- if (!f)
- {
- perror(filename);
- return 1;
- }
- int looksbinary = isbinary || testbinary(f);
- int c;
-
- if (!looksbinary)
- {
- return sendtextsyx(f, 0) != 0;
- }
- else
- {
- if (count <= 0)
- count = 0x7fffffffL;
-
- if (skip < 0)
- skip = 0;
-
- encode = binaryencode;
- if (encode && echo)
- printf("<encoded data> ");
- fseek(f, skip, SEEK_SET);
- skip = 0;
- c = fgetc(f);
- // assume binary
- while (c != EOF && count > 0)
- {
- if (escape())
- break;
- count--;
- if (!sendbyte(c))
- break;
- c = fgetc(f);
- }
- encode = 0;
- count = 0;
- }
-
- fclose(f);
- return 0;
- }
-
- int main(int argc, char** argv)
- {
- argc--; argv++;
-
- int ret = 0;
-
- if (argc == 0)
- {
- printf("%s\n", version);
- printf("usage: sysex [-noreply] [-skip #] [-count #] [-echo] [-enc] [-raw] [hex] [cmd] [file] ...\n");
- printf("-noreply don't wait for a reply\n");
- printf("-skip # skip bytes of next binary file\n");
- printf("-count # read count bytes of next binary file (default: read till end)\n");
- printf("-echo echo sent bytes in hexadecimal format\n");
- printf("-enc dump encode bytes read from binary files\n");
- printf("-raw do not encode bytes read from binary files\n");
- printf("hex send byte (e.g. f0 42 a f7)\n");
- printf("cmd send command (e.g. gmon notesoff ...)\n");
- printf("file end content of binary or hex file\n");
- printf("All parameters can be used more than once. Text files can contain hex, cmd, file\n");
- printf("-skip,-count,-enc only affect next binary file\n");
- return 1;
- }
-
- card = detect_soundcard();
- if (!card)
- {
- fprintf(stderr, "Could not detect soundcard\n");
- return 1;
- }
-
- checkresponse();
-
- while (argc > 0)
- {
- if (escape())
- break;
- if (**argv == '-')
- {
- if (strnicmp(*argv, "-version", 2) == 0)
- {
- fprintf(stderr, "%s\n", version);
- *argv = 0;
- argc--; argv++;
- }
- if (strnicmp(*argv, "-binary", 2) == 0)
- {
- isbinary = 1;
- argc--; argv++;
- continue;
- }
- if (strnicmp(*argv, "-noreply", 2) == 0)
- {
- reply = 0;
- argc--; argv++;
- continue;
- }
- if (strnicmp(*argv, "-encode", 3) == 0)
- {
- binaryencode = 1;
- argc--; argv++;
- continue;
- }
- if (strnicmp(*argv, "-raw", 2) == 0)
- {
- encode = 0;
- argc--; argv++;
- continue;
- }
- if (strnicmp(*argv, "-echo", 2) == 0)
- {
- echo = 1;
- argc--; argv++;
- continue;
- }
- if (strnicmp(*argv, "-skip", 2) == 0)
- {
- argc--; argv++;
- if (argc == 0 || !isxdigit(**argv))
- fprintf(stderr, "option -skip needs a value\n");
- else
- {
- char* endptr = 0;
-
- skip = strtoul(*argv, &endptr, 0);
- if (endptr && *endptr)
- fprintf(stderr, "%s is not a legal value\n", *argv);
- argc--; argv++;
- }
- continue;
- }
- if (strnicmp(*argv, "-count", 2) == 0)
- {
- argc--; argv++;
- if (argc == 0 || !isxdigit(**argv))
- fprintf(stderr, "option -count needs a value\n");
- else
- {
- char* endptr = 0;
-
- count = strtoul(*argv, &endptr, 0);
- if (endptr && *endptr)
- fprintf(stderr, "%s is not a legal value\n", *argv);
- argc--; argv++;
- }
- continue;
- }
- fprintf(stderr, "invalid option %s\n", *argv);
- argc--; argv++; continue;
- }
- else
- {
- char* arg = *argv++; argc--;
- int arglen = strlen(arg);
-
- if (arglen == 0)
- continue;
- sendtextsyx(0, arg);
- }
- }
-
- if (sum > 0 && reply)
- {
- printf("\n%ld bytes sent, ", sum);
- checkreply();
- }
-
- delete card;
- return ret;
- }
-